package Unit

import (
	"container/list"
	//"fmt"
)

const (
	CommandType_Move   = 0
	CommandType_Attack = 1
)

type Command struct {
	CommandType int32
	IntArgs     []int32
	FloatArgs   []float32
	StrArgs     []string
}

type CommandExecFn func(intArgs []int32, floatArgs []float32, strArgs []string)

type CommandQueue struct {
	CommandList *list.List
	PushEvents  map[int][]CommandExecFn
}

func NewCommandQueue() *CommandQueue {
	cmdQueue := &CommandQueue{}
	cmdQueue.CommandList = list.New()
	cmdQueue.PushEvents = make(map[int][]CommandExecFn)
	return cmdQueue
}

func (this *CommandQueue) AddEvent(commonType int, fn CommandExecFn) {
	if _, ok := this.PushEvents[commonType]; !ok {
		this.PushEvents[commonType] = make([]CommandExecFn, 0)
	}
	this.PushEvents[commonType] = append(this.PushEvents[commonType], fn)
}

func (this *CommandQueue) ExecEvent(command *Command) {
	for _, v := range this.PushEvents[int(command.CommandType)] {
		v(command.IntArgs, command.FloatArgs, command.StrArgs)
	}
}

func (this *CommandQueue) Current() *Command {
	if this.CommandList == nil || this.CommandList.Front() == nil {
		return nil
	}
	return this.CommandList.Front().Value.(*Command)
}

func (this *CommandQueue) Push(commandType int32, intArgs []int32, floatArgs []float32, strArgs []string) *Command {
	cmd := &Command{}
	cmd.CommandType = commandType
	cmd.IntArgs = intArgs
	cmd.FloatArgs = floatArgs
	cmd.StrArgs = strArgs
	this.CommandList.PushBack(cmd)
	if this.CommandList.Len() == 1 {
		this.ExecEvent(cmd)
	}
	return cmd
}

func (this *CommandQueue) Pop() {
	this.CommandList.Remove(this.CommandList.Front())
	if this.CommandList.Len() > 0 {
		this.ExecEvent(this.Current())
	}
}

func (this *CommandQueue) Clear() {
	this.CommandList.Init()
}
